package com.stars.easyms.logger.support.logback.sift;

import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.Appender;
import ch.qos.logback.core.joran.action.ActionConst;
import ch.qos.logback.core.joran.spi.*;
import ch.qos.logback.core.sift.SiftingJoranConfiguratorBase;
import com.stars.easyms.logger.support.EasyMsOverride;
import com.stars.easyms.logger.support.logback.joran.action.EasyMsAppenderAction;
import com.stars.easyms.logger.support.logback.joran.spi.EasyMsSimpleRuleStore;
import com.stars.easyms.logger.support.logback.util.EasyMsDefaultNestedComponentRules;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>className: EasyMsSiftingJoranConfigurator</p>
 * <p>description: 重写SiftingJoranConfigurator类</p>
 *
 * @author guoguifang
 * @date 2019-08-20 16:06
 * @since 1.3.0
 */
public final class EasyMsSiftingJoranConfigurator extends SiftingJoranConfiguratorBase<ILoggingEvent> implements EasyMsOverride {

    EasyMsSiftingJoranConfigurator(String key, String value, Map<String, String> parentPropertyMap) {
        super(key, value, parentPropertyMap);
    }

    @Override
    protected ElementPath initialElementPath() {
        return new ElementPath("configuration");
    }

    @Override
    protected void addInstanceRules(RuleStore rs) {
        super.addInstanceRules(rs);
        rs.addRule(new ElementSelector("configuration/appender"), new EasyMsAppenderAction<ILoggingEvent>());
    }

    @Override
    protected void addDefaultNestedComponentRegistryRules(DefaultNestedComponentRegistry registry) {
        EasyMsDefaultNestedComponentRules.addDefaultNestedComponentRegistryRules(registry);
    }

    @Override
    protected void buildInterpreter() {
        RuleStore rs = new EasyMsSimpleRuleStore(context);
        addInstanceRules(rs);
        this.interpreter = new Interpreter(context, rs, initialElementPath());
        InterpretationContext interpretationContext = interpreter.getInterpretationContext();
        interpretationContext.setContext(context);
        addImplicitRules(interpreter);
        addDefaultNestedComponentRegistryRules(interpretationContext.getDefaultNestedComponentRegistry());
        Map<String, Object> omap = interpretationContext.getObjectMap();
        omap.put(ActionConst.APPENDER_BAG, new HashMap<String, Appender<?>>(32));
        Map<String, String> propertiesMap = new HashMap<>(parentPropertyMap);
        propertiesMap.put(key, value);
        interpreter.setInterpretationContextPropertiesMap(propertiesMap);
    }

    @Override
    @SuppressWarnings("unchecked")
    public Appender<ILoggingEvent> getAppender() {
        Map<String, Object> omap = interpreter.getInterpretationContext().getObjectMap();
        HashMap<String, Appender<?>> appenderMap = (HashMap<String, Appender<?>>) omap.get(ActionConst.APPENDER_BAG);
        oneAndOnlyOneCheck(appenderMap);
        Collection<Appender<?>> values = appenderMap.values();
        if (values.isEmpty()) {
            return null;
        }
        return (Appender<ILoggingEvent>) values.iterator().next();
    }
}